package org.dromara.northstar.analysis;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

import com.google.protobuf.InvalidProtocolBufferException;

import xyz.redtorch.pb.CoreField.BarField;

/**
 * BAR 表数据分析工具
 * 用于诊断策略为什么不触发交易
 */
public class BarDataAnalyzer {

    // 获取项目根目录
    private static final String PROJECT_ROOT = System.getProperty("user.dir").contains("northstar-main")
            ? ".."
            : ".";
    private static final String DB_URL = "jdbc:h2:file:" + PROJECT_ROOT + "/data/storage";
    private static final String DB_USER = "sa";
    private static final String DB_PASSWORD = "";
    
    public static void main(String[] args) {
        System.out.println("=".repeat(80));
        System.out.println("Northstar K-Line Data Analysis Tool");
        System.out.println("=".repeat(80));
        
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            
            // 1. 统计今天的K线数量
            analyzeTodayBarCount(conn);
            
            // 2. 分析最近50根K线
            analyzeRecentBars(conn, 50);
            
            // 3. 检测价格波动
            analyzePriceVolatility(conn, 20);
            
        } catch (Exception e) {
            System.err.println("[ERROR] " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 统计今天的K线数量
     */
    private static void analyzeTodayBarCount(Connection conn) throws Exception {
        System.out.println("\n[SECTION 1] Today's K-Line Statistics");
        System.out.println("-".repeat(80));
        
        String sql = "SELECT unified_symbol, COUNT(*) as cnt, " +
                     "MIN(trading_day) as minDay, MAX(trading_day) as maxDay " +
                     "FROM BAR " +
                     "WHERE trading_day = FORMATDATETIME(CURRENT_DATE(), 'yyyy-MM-dd') " +
                     "GROUP BY unified_symbol";
        
        try (PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            
            boolean hasData = false;
            while (rs.next()) {
                hasData = true;
                System.out.printf("Contract: %s | K-Line Count: %d | Trading Day: %s%n",
                    rs.getString("unifiedSymbol"),
                    rs.getInt("cnt"),
                    rs.getString("minDay"));
            }
            
            if (!hasData) {
                System.out.println("[WARNING] No K-Line data today!");
                System.out.println("    Possible reasons:");
                System.out.println("    1. Using SIM gateway (SIM data is not stored in database)");
                System.out.println("    2. Gateway not connected or contract not subscribed");
                System.out.println("    3. Service just started, K-Line not generated yet");
            }
        }
    }
    
    /**
     * 分析最近的K线数据
     */
    private static void analyzeRecentBars(Connection conn, int limit) throws Exception {
        System.out.println("\n[SECTION 2] Recent " + limit + " K-Lines Details");
        System.out.println("-".repeat(80));
        
        String sql = "SELECT id, unified_symbol, trading_day, expired_at, bar_data " +
                     "FROM BAR " +
                     "ORDER BY expired_at DESC " +
                     "LIMIT ?";
        
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, limit);
            
            try (ResultSet rs = ps.executeQuery()) {
                int count = 0;
                double prevClose = 0;
                
                System.out.printf("%-6s %-20s %-20s %-10s %-10s %-10s %-10s%n",
                    "ID", "Contract", "Time", "Open", "High", "Low", "Close");
                System.out.println("-".repeat(80));
                
                while (rs.next()) {
                    count++;
                    byte[] barData = rs.getBytes("bar_data");
                    
                    try {
                        BarField bar = BarField.parseFrom(barData);
                        
                        // 转换时间戳
                        long timestamp = bar.getActionTimestamp();
                        LocalDateTime dateTime = LocalDateTime.ofInstant(
                            Instant.ofEpochMilli(timestamp), 
                            ZoneId.systemDefault()
                        );
                        String timeStr = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                        
                        // 打印K线信息
                        System.out.printf("%-6d %-20s %-20s %-10.2f %-10.2f %-10.2f %-10.2f",
                            rs.getInt("id"),
                            bar.getUnifiedSymbol(),
                            timeStr,
                            bar.getOpenPrice(),
                            bar.getHighPrice(),
                            bar.getLowPrice(),
                            bar.getClosePrice());
                        
                        // 计算涨跌
                        if (prevClose > 0) {
                            double change = ((bar.getClosePrice() - prevClose) / prevClose) * 100;
                            System.out.printf(" (%.2f%%)%n", change);
                        } else {
                            System.out.println();
                        }
                        
                        prevClose = bar.getClosePrice();
                        
                    } catch (InvalidProtocolBufferException e) {
                        System.out.printf("%-6d %-20s %-20s  [Data Parse Failed]%n",
                            rs.getInt("id"),
                            rs.getString("unifiedSymbol"),
                            "");
                    }
                }
                
                if (count == 0) {
                    System.out.println("[WARNING] No K-Line data in database!");
                }
            }
        }
    }
    
    /**
     * 分析价格波动（用于判断是否能触发交易）
     */
    private static void analyzePriceVolatility(Connection conn, int limit) throws Exception {
        System.out.println("\n[SECTION 3] Price Volatility Analysis (Recent " + limit + " K-Lines)");
        System.out.println("-".repeat(80));
        
        String sql = "SELECT bar_data FROM BAR ORDER BY expired_at DESC LIMIT ?";
        
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, limit);
            
            try (ResultSet rs = ps.executeQuery()) {
                double[] closes = new double[limit];
                int count = 0;
                
                while (rs.next() && count < limit) {
                    byte[] barData = rs.getBytes("bar_data");
                    try {
                        BarField bar = BarField.parseFrom(barData);
                        closes[count++] = bar.getClosePrice();
                    } catch (InvalidProtocolBufferException e) {
                        // 跳过解析失败的数据
                    }
                }
                
                if (count < 2) {
                    System.out.println("[WARNING] Insufficient K-Line data, cannot analyze volatility");
                    return;
                }
                
                // 计算价格统计
                double max = closes[0];
                double min = closes[0];
                double sum = 0;
                
                for (int i = 0; i < count; i++) {
                    if (closes[i] > max) max = closes[i];
                    if (closes[i] < min) min = closes[i];
                    sum += closes[i];
                }
                
                double avg = sum / count;
                double range = max - min;
                double rangePercent = (range / avg) * 100;
                
                System.out.printf("Price Range: %.2f - %.2f%n", min, max);
                System.out.printf("Average Price: %.2f%n", avg);
                System.out.printf("Volatility: %.2f (%.2f%%)%n", range, rangePercent);
                
                // 模拟 EMA1 和 EMA2
                if (count >= 2) {
                    double ema1 = closes[0];  // EMA1 = 当前收盘价
                    double ema2 = (closes[0] * 2.0 / 3.0) + (closes[1] * 1.0 / 3.0);  // EMA2 近似
                    
                    System.out.println("\nSimulated Indicators (Latest K-Line):");
                    System.out.printf("  EMA1 (Fast Line): %.2f%n", ema1);
                    System.out.printf("  EMA2 (Slow Line): %.2f%n", ema2);
                    System.out.printf("  Difference: %.2f (%.2f%%)%n", 
                        ema1 - ema2, 
                        ((ema1 - ema2) / ema2) * 100);
                    
                    if (ema1 > ema2) {
                        System.out.println("  -> Fast line above slow line, should BUY/HOLD LONG");
                    } else if (ema1 < ema2) {
                        System.out.println("  -> Fast line below slow line, should SELL/HOLD SHORT");
                    } else {
                        System.out.println("  -> Fast and slow lines equal, wait and see");
                    }
                }
                
                // 检测交叉点
                System.out.println("\nGolden Cross / Death Cross Detection (Recent 5 K-Lines):");
                for (int i = 0; i < Math.min(5, count - 1); i++) {
                    double ema1_curr = closes[i];
                    double ema2_curr = (closes[i] * 2.0 / 3.0) + (closes[i+1] * 1.0 / 3.0);
                    
                    double ema1_prev = closes[i+1];
                    double ema2_prev = i+2 < count ? 
                        (closes[i+1] * 2.0 / 3.0) + (closes[i+2] * 1.0 / 3.0) : ema2_curr;
                    
                    boolean crossUp = ema1_prev <= ema2_prev && ema1_curr > ema2_curr;
                    boolean crossDown = ema1_prev >= ema2_prev && ema1_curr < ema2_curr;
                    
                    if (crossUp) {
                        System.out.printf("  [%d] [GOLDEN CROSS] Fast line crosses above slow line, trigger BUY OPEN / SELL CLOSE%n", i);
                    } else if (crossDown) {
                        System.out.printf("  [%d] [DEATH CROSS] Fast line crosses below slow line, trigger SELL OPEN / BUY CLOSE%n", i);
                    }
                }
            }
        }
    }
}





